MODULE fmm_global_consts

   USE fmm_global_types
   IMPLICIT NONE
   PUBLIC   

!==============================================================================
! Program-wide global variables |
!===============================!

   ! We select here the REAL and INTEGER precisions
   !   INTEGER, PARAMETER :: md1_INTK  = SELECTED_INT_KIND(9),           &
   !                         md1_REALK = SELECTED_REAL_KIND(XXX) 
   ! Use standard integers and REAL*8 double precision floats
   INTEGER, PARAMETER :: INTK  = KIND(1),                         &
                         REALK = KIND(1D0)

    ! Unit numbers for IO
   INTEGER(INTK), SAVE :: IO1 = 888
   INTEGER(INTK), SAVE :: IO2 = 889

    ! Flag for verbose printing of run-time statistics
   LOGICAL, SAVE :: fmm_stats_printed = .TRUE.
 
!==============================================================================
! Global parameters |
!===================!

   REAL(REALK), PARAMETER :: zero   = 0.0_REALK,                        &
                             one    = 1.0_REALK,                        &
                             two    = 2.0_REALK,                        &
                             half   = 0.5_REALK,                        &
                             PI     = 3.14159265358979323846264_REALK,  &
                             ROOTPI = 1.77245385090552_REALK,           &
                             ROOT2  = 1.41421356237310_REALK,           &
                             ROOT3  = 1.73205080756888_REALK,           &
                             IROOT2 = 0.707106781186548_REALK,          &
                             LOG_10 = 2.30258509299405_REALK
 
!------------------------------------------------------------------------------

   ! Branch-free algorithm
   LOGICAL,     PARAMETER :: BRFREE_DF = .TRUE.
   ! minimum charge separation for qTq evaluation
   REAL(REALK), PARAMETER :: EXTENT_MIN_DF = 0.001_REALK

   ! Same centre/extent packing flags
   LOGICAL, PARAMETER :: PACK_RHS_DF = .TRUE.
   LOGICAL, PARAMETER :: PACK_LHS_DF = .FALSE.

    ! Parameters for branch and box structure
!   INTEGER(INTK), PARAMETER :: WS_MIN = 2
   INTEGER(INTK), PARAMETER :: WS_MIN = 1
   LOGICAL,       PARAMETER :: JOIN_BRANCHES = .TRUE. 
 
    ! Parameters for T-list tree sorting
   INTEGER(INTK), PARAMETER :: START_LEN   = 8
   INTEGER(INTK), PARAMETER :: TREE_LENGTH = 1000000
   ! MAX_AVG_PER_NODE limits the maximal packing ratio.
   ! there will be never more interactions in the tree than
   ! tree size times MAX_AVG_PER_NODE.
   INTEGER(INTK), PARAMETER :: MAX_AVG_PER_NODE = 15
 
    ! Noise buffer when testing for classical interactions
 !FIXME: have this passed from clsfmm.h ... used for nothing else!!
   REAL(REALK), PARAMETER :: ZERO_DIST_TOL = 1e-14_REALK
 
    ! Parameters for contractions and translations
   ! Number of simultaneous T-matrices when using T_CONTRACTOR_MULTI
   INTEGER(INTK), PARAMETER :: TMATM_DF = 25

 !FIXME: clarify the use of these tolerance parameters!!
   REAL(REALK), PARAMETER :: DISTINCT_T_TOL  = 1e-15_REALK
   REAL(REALK), PARAMETER :: EXTENT_TEST_TOL = 1e-15_REALK
   REAL(REALK), PARAMETER :: ZERO_VECT_TOL   = 1e-10_REALK
 
!------------------------------------------------------------------------------

    ! Parameters to define level depth used in box hierarchy
   INTEGER(INTK), PARAMETER :: TOP_LEVEL = 2
   INTEGER(INTK), PARAMETER :: MAX_LEVEL = 15

!------------------------------------------------------------------------------
!
! Named parameters for coding use (avoidance of "magic" numbers etc.)
!
    ! Named parameters for potential or J-matrix request jobtype
   INTEGER(INTK), PARAMETER :: GFC_FMM  = 1,   &
                               MD4_FMM  = 2,   &
                               FE_FMM   = 3,   &
                               QCIM_FMM = 4,   &
                               PBC_FMM  = 5

    ! Named parameters for (classical) near-field or far-field phase
   INTEGER(INTK), PARAMETER :: NEAR_FIELD = 1 ,    &
                               FAR_FIELD  = 2

    ! Named parameters for different MM methods implemented
   INTEGER(INTK), PARAMETER :: DO_NULL  = 0 ,     &
                               DO_FQ    = 1 ,     &
                               DO_BQ    = 3 ,     &
                               DO_NlogN = 4 ,     &
                               DO_FMM   = 5 

    ! Named parameters for T-pair interaction types
   INTEGER(INTK), PARAMETER :: LHS_raw_RHS_raw = 1,     &
                               LHS_raw_RHS_box = 2,     &
                               LHS_box_RHS_raw = 3,     &
                               LHS_box_RHS_box = 4

    ! Named parameters for T-pair interaction search algorithms
   INTEGER(INTK), PARAMETER :: FQ_LOOPS    = 1,     &
                               GRID_SEARCH = 2,     &
                               TREE_SEARCH = 3

    ! Named parameters for different contractors implemented
   INTEGER(INTK), PARAMETER :: T_CONTRACTOR_DIRECT = 100,        &
                               T_CONTRACTOR_BOUNDARY = 101,      &
                               T_CONTRACTOR_TREE = 102,          &
                               T_CONTRACTOR_SCALE = 104,         &
                               T_CONTRACTOR_SCALE_TREE = 1041,   &
                               T_CONTRACTOR_MULTI = 105,         &
                               T_CONTRACTOR_FULL = 106,          &
                               W_CONTRACTOR_DIRECT = 206,        &
                               W_CONTRACTOR_X = 207,             &
                               W_CONTRACTOR_FAST = 208,          &
                               W_CONTRACTOR_BOUNDARY = 209
 
    ! Named parameters for different J-builders (contractors) implemented
   INTEGER(INTK), PARAMETER :: J_BUILDER_DIRECT = 1,        &
                               J_BUILDER_TREE = 2

    ! Named parameters for use of 1-el, 2-el, or just potential job type
   INTEGER(INTK), PARAMETER :: ELECTRONIC_ONLY = 1,        &
                               NUCLEAR_ONLY    = 2,        &
                               ALL_MOMENTS     = 3,        &
                               POTENTIAL_ONLY  = 4
 
    ! Named parameters for T-pair interaction tests
   INTEGER(INTK), PARAMETER :: TEST_EXT     = 1,        &
                               TEST_R_IJ    = 2,        &
                               TEST_NN_EXT  = 3,        &
                               TEST_NN_R_IJ = 4,        &
                               TEST_FF      = 5,        &
                               TEST_LFF     = 6

    ! Named parameters for auxiliary moments
   INTEGER(INTK), PARAMETER :: USE_RAW_QLM   = 0 ,        &
                               USE_T_SYM_QLM = 1 
 
    ! Named parameters for lists available 
   INTEGER(INTK), PARAMETER :: NULL_T_BUFFER  = 1 ,        &
                               NULL_W_BUFFER  = 2 ,        &
                               TREE_T_BUFFER  = 3 ,        &
                               TREE_W_BUFFER  = 4 ,        &
                               SKIP_T_BUFFER  = 5 ,        &
                               SKIP_W_BUFFER  = 6 ,        &
                               MULTI_T_BUFFER = 7 ,        &
                               SCALE_T_BUFFER = 8

    ! Sort orders expected by interaction evaluators.
   INTEGER(INTK), PARAMETER :: NO_SORT         = 0 ,       &
                               SORT_BY_SCALE   = 1,        &
                               SORT_BY_RHS_MMS = 2
 
    ! Named parameters for memory management
   INTEGER(INTK), PARAMETER :: NMEMDIVS = 5
   CHARACTER(7),  PARAMETER :: NSPACE(NMEMDIVS) = (/ 'raw_qlm',   &
                                                     'raw_Vff',   &            
                                                     'box_Vff',   &            
                                                     'Vff_tmp',   &            
                                                     'box_qlm' /)
   INTEGER(INTK), PARAMETER :: MEM_RAW_QLM = 1,        &
                               MEM_RAW_VFF = 2,        &
                               MEM_BOX_VFF = 3,        &
                               MEM_VFF_TMP = 4,        &
                               MEM_BOX_QLM = 5

!------------------------------------------------------------------------------

END MODULE fmm_global_consts
